#include <mips/regdef.h>
#include <sys/syscall.h>

#define STD_IN 0
#define STD_OUT 1
#define STD_ERROR 2

#define CANT_REALLOC 100
#define SRA 36
#define LA 16 
#define ABA 0 
#define SS 48
.data 
msj_error: .asciiz "Error en la asignacion de memoria\n"

.text
.align 2
.globl main
.ent main


main:
.frame $fp,48,ra
.set noreorder
.cpload t9
.set reorder
subu sp,sp,SS
.cprestore SRA
sw $fp, SRA+4(sp)
sw ra, SRA+8(sp)

move $fp,sp
m1:
move a0,zero
li a1, CANT_REALLOC
jal realocar #asigno el tamaño del buffer por primera vez

m2: 
#chequeo
move t7,v0
sw v0,LA(sp) #guardamos direccion al puntero al buffer
addu t4, zero, CANT_REALLOC #tamaño buffer
addu t3,zero,zero

#LA 
#0 - DIR del buffer
#4 - Puntero a la ultima pos del buffer alamcenada
#8 - contador
#12 - tamaño del buffer (memoria allocada)

while:

        sw t7, LA+4(sp) # guarda buffer antes de la llamada a read.
        sw t3, LA+8(sp) # guarda contador antes de la llamada a read.
        sw t4, LA+12(sp) # guarda tamaño del buffer

        bne t3,t4,jump #salteo el realocar ( no la estamos guardando arriba)      
                lw a0,LA(sp)
                mul a1,t4,2 #el nuevo tamaño del buffer es 2*tamaño viejo
                sw a1, LA+12(sp) # guarda tamaño del buffer
                jal realocar
                lw t3,LA+8(sp)
                sw v0,LA(sp) # guardo el nuevo buffer ya que realocar puede moverlo de posición. 
                addu t7,t3,v0 # volver a poner la posición del buffer en el nuevo bloque.
                sw t7,LA+4(sp) # guarda buffer antes de la llamada a read.
     
        jump:

        #preparo llamada al read
        li a0,STD_IN #file Descriptor STDIN
        move a1, t7  #Puntero al buffer
        li a2,1  #tamano a leer
        m4:jal read

        lw t7, LA+4(sp) #lo carga otra vez.
        lw t3, LA+8(sp) #lo carga otra vez.
        lw t4, LA+12(sp) #lo carga otra vez.

        addu t3,t3,1 # aumento el contador.
        addu t7,t7,1 #muevo el puntero al buffer la cant de posiciones q lei.
        bne v0,1,eof #comparo el ultimo caracter leido a ver si es fin de archivo.
b while


error:
li a0,STD_OUT 
la a1,msj_error 
li a2,3
jal write
li v0,SYS_exit
syscall


eof:

lw a0,LA(sp)
lw a1,LA+8(sp)
jal imprimir
lw a0,LA(sp) #recupera la posición del buffer para liberarlo.
jal desalocar
move v0, zero
move sp,$fp
lw ra,SRA+8(sp)#recupero ra
lw $fp,SRA+4(sp)
addu sp,sp,48
j ra # vuelvo al sistema operativo.

.end main
